//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//
//	File		 :	PerlUtil.cpp
//	Creation Date:	25/01/2000
//	Last Modified:	25/01/2000	lg
//	tabs width	 :	every 4 characters
//
//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

#include <string>

#include "perlutil.h"
#define _MY_STL_MACROS
#include "stlhelper.h"

using std::string;
using std::vector;
using std::pair;

string PerlStrip(string s)
{
	string::size_type last = s.find_last_not_of("\r\n");
	if (last == string::npos)
		return "";
	s.erase(s.begin() + (last+1), s.end());
	return s;
}

string PerlJoin (const vector<string>& strs, const string& link, unsigned beg)
{
	string ret;
	for (unsigned int i = beg; i < strs.size(); ++i)
		ret += strs[i] + link;

	return ret;
}

vector<string>& perl_split (const string& str, const string& delimiters,
									vector<string>& ret, bool ignoreEmpty, unsigned max_cnt)
{
	// array of strings to return
	ret.clear();

	string::size_type beg = 0;
	string::size_type end = string::npos;
	while ((end = str.find_first_of(delimiters, beg)) != string::npos)
	{
		if (end != beg || !ignoreEmpty)
			ret.push_back(str.substr(beg, end - beg));
		beg = end + 1;

		if (ret.size() >= max_cnt-1)
			break;
	}

	ret.push_back(str.substr(beg));


	return ret;
}

vector<string>& perl_split (const char*& text, string delimiters, vector<string>& ret)
{
	// array of strings to return
	ret.clear();

	// find end of line (null or 0)
	const char* strEnd = strcspn(text, "\r\n") + text;


	// delimiters must include new line
	delimiters += "\r\n";

	const char* strTokBeg = text;

	// does nothing if empty line
	while (strTokBeg < strEnd)
	{
		size_t tokenEnd = strcspn(strTokBeg, delimiters.c_str());
		if (tokenEnd)
			ret.push_back(string(strTokBeg, tokenEnd));
		else
			// push back empty string for empty tokens
			ret.push_back(string());
		strTokBeg += tokenEnd + 1;
	}

	// put a null at the end of the line
	if (!*strEnd)
		text = 0;
	else
	{
		// cope with both unix and windows line delimiters
		if (*strEnd == '\r' && *strEnd == '\n')
			text = strEnd + 2;
		else
			text = strEnd + 1;
	}
	return ret;
}

vector<pair<string::iterator,	string::iterator> >&
perl_split (	const string::iterator&									str_beg,
			const string::iterator&									str_end,
			const string&											delimiters,
			vector<pair<string::iterator, string::iterator> >&  	ret,
			bool													ignoreEmpty,
			unsigned												max_cnt)
{
	// array of strings to return
	ret.clear();

	string::iterator find_start	=	str_beg;
	string::iterator found		=	str_end;
	while ((found = find_first_of(find_start, str_end, beg_to_end(delimiters))) != str_end)
	{
		if (!ignoreEmpty || find_start != found)
			ret.push_back(std::make_pair(find_start, found));
		find_start = found + 1;
		if (ret.size() >= max_cnt)
			return ret;
	}

	if (!ignoreEmpty || find_start != found)
		ret.push_back(std::make_pair(find_start, found));
	return ret;
}

